package service

import (
    "authserver/global"
    "authserver/utils"
    "crypto/tls"
    "encoding/binary"
    "fmt"
    "github.com/gorilla/websocket"
    "log"
    "net/http"
    "os"
    "strings"
    "time"
)

func TextToAudio(text,modelType string,rate,pitch int) (err error,filePath string)  {

    fmt.Println("video-path: ",global.GVA_CONFIG.EdgeTts.VideoPath)

    baseUrl:="wss://speech.platform.bing.com/consumer/speech/synthesize/readaloud/edge/v1?TrustedClientToken=%s&Sec-MS-GEC=%s&Sec-MS-GEC-Version=%s&ConnectionId=%s"
    TrustedClientToken = "6A5AA1D4EAFF4E9FB37E23D68491D6F4"
    SecMsgEc:=GenerateSecMsGec()
    SecMsgEcVersion:="1-133.0.3065.82"
    connectionId:= utils.GetUUidString()

    url := fmt.Sprintf(baseUrl,TrustedClientToken,SecMsgEc,SecMsgEcVersion,connectionId)
    dialer := websocket.DefaultDialer
    dialer.TLSClientConfig = &tls.Config{InsecureSkipVerify: true} // 跳过证书验证，仅用于示例目的

    headerMap:=map[string]string{
        "Pragma": "no-cache",
        "Cache-Control": "no-cache",
        "Origin": "chrome-extension://jdiccldimpdaibmpdkjnbmckianbfold",
        "Accept-Encoding": "gzip, deflate, br",
        "Accept-Language": "en-US,en;q=0.9",
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36 Edg/133.0.0.0",
    }

    header:=http.Header{}

    for k,v:=range headerMap{
        header.Add(k,v)
    }

    // 发起WebSocket连接
    conn, _, err := dialer.Dial(url, header)
    if err != nil {
        log.Println("WebSocket连接失败:", err)
        return
    }
    defer conn.Close()

    randomTimeStamp:=time.Now().Unix()

    configMessage := "X-Timestamp:%d\r\n" +
        "Content-Type:application/json; charset=utf-8\r\n" +
        "Path:speech.config\r\n\r\n " +
        "%s\r\n"

    config:=`{"context":{"synthesis":{"audio":{"metadataoptions":{"sentenceBoundaryEnabled":false,"wordBoundaryEnabled":true},"outputFormat":"audio-24khz-48kbitrate-mono-mp3"}}}}`

    configMessageStr:=fmt.Sprintf(configMessage,randomTimeStamp,config)
    fmt.Println(configMessageStr)

    // 发送配置信息
    err=conn.WriteMessage(websocket.TextMessage,[]byte(configMessageStr))
    if err!=nil{
        log.Println("发送消息错误:", err)
        return
    }

    // 发送文本信息
    audioByte:=make([]byte,0)

    text=strings.ReplaceAll(text,"\r\n","\n")
    textArr:=strings.Split(text,"\n")
    tempByte:=make([]byte,0)
    for _,v:=range textArr{
        // 发送消息
        err,tempByte = SendMsg(conn,modelType,v,rate,pitch)
        if err != nil {
            log.Fatal("发送消息错误:", err)
        }
        audioByte = append(audioByte, tempByte...)
    }

    randKey :=strings.ToUpper(utils.GetUUidString())+".mp3"
    randKey = "tts-video/"+randKey

    f,err:=os.Create(randKey)
    if err!=nil{
        log.Println(err.Error())
        return
    }
    _,err=f.Write(audioByte)
    if err!=nil{
        log.Println(err.Error())
        return
    }
    f.Close()

    videoPath := global.GVA_CONFIG.EdgeTts.VideoPath + randKey

    return nil,videoPath
}


// 发送请求

func SendMsg(conn *websocket.Conn,shortName,text string,rate,pitch int) (err error,audioByte []byte) {

    SSMLFormat := `
    <speak xmlns="http://www.w3.org/2001/10/synthesis" xmlns:mstts="http://www.w3.org/2001/mstts" xmlns:emo="http://www.w3.org/2009/10/emotionml" version="1.0" xml:lang="en-US">
        <voice name="%s">
            <prosody rate="%d%%" pitch="%d%%">
            %s
            </prosody>
        </voice>
    </speak>`

    if rate ==0{
        rate = 1
    }
    if pitch == 0{
        pitch=1
    }

    ssmlContent:=fmt.Sprintf(SSMLFormat,shortName,rate,pitch,text)

    randKey :=utils.GetUUidString()
    randKey = strings.ToLower(randKey)

    randomTimeStamp:=time.Now().Unix()

    ssmlMessage :=
        "X-Timestamp:%d\r\n" +
            "X-RequestId:%s\r\n"+
            "Content-Type:application/ssml+xml\r\n" +
            "Path:ssml\r\n\r\n" +
            "%s"

    ssmlMessage = fmt.Sprintf(ssmlMessage,randomTimeStamp,randKey,ssmlContent)

    fmt.Println(ssmlMessage)

    err = conn.WriteMessage(websocket.TextMessage,[]byte(ssmlMessage))

    if err!=nil{
        log.Fatal("发送消息错误:", err)
        return
    }

    audioInfo:=make([][]byte,0)
    for {
        msgType, message, err1 := conn.ReadMessage()
        if err1 != nil {
            log.Println("读取消息错误:", err1)
            return
        }
        if msgType == websocket.TextMessage{
            txtMsg:=string(message)
            if strings.Contains(txtMsg,"Path:turn.start"){
                log.Println("开始接收消息")
            }
            if strings.Contains(txtMsg,"Path:turn.end"){
                log.Println("传输结束")
                break
            }
        }
        if msgType == websocket.BinaryMessage{
            audioInfo = append(audioInfo, message)
            //log.Printf("收到binary 消息: %d", len(message))
        }
    }

    for i:=0;i< len(audioInfo);i++{
        if len(audioInfo[i])<2{
            log.Println("We received a binary message, but it is missing the header length.")
            break
        }
        headLen := binary.BigEndian.Uint16(audioInfo[i][:2])
        audioInfo[i] = audioInfo[i][headLen+2:]
    }

    audioByte=make([]byte,0)
    for _,v:=range audioInfo{
        audioByte=append(audioByte, v...)
    }

    return nil,audioByte
}
